package us.gaaoc.framework.webapp.backingbeans.viewOnly;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.hibernate.Hibernate;

import us.gaaoc.framework.model.CaseRecord;
import us.gaaoc.framework.model.Documents;
import us.gaaoc.framework.model.OrgParticipants;
import us.gaaoc.framework.model.Person;
import us.gaaoc.framework.model.PersonParticipants;
import us.gaaoc.framework.util.LocalCaseInformation;
import us.gaaoc.framework.webapp.backingbeans.BaseBackingBean;

/**
 * 
 * @author tapshals
 * @date May 24, 2006
 * @version: GAJE 1.5
 * 
 */
@SuppressWarnings("unchecked")
public class CaseDetailsPage extends BaseBackingBean {

	/**
	 * Properties
	 */
	
	/** Generated Serial Version UID */
	private static final long serialVersionUID = -4933319608677991014L;
	
	private CaseRecord caseRecord;

	private String filerName;

	private Date courtDate, proposedCourtDate, originalCourtDate;
	
	/**
	 * Data Models for the personParticipants
	 */
	private DataModel initiatingPartyPersonModel;

	private DataModel defendentPartyPersonModel;

	private DataModel witnessPersonModel;

	private DataModel plantiffsAttorneyModel;

	private DataModel defendentsAttorneyModel;

	private DataModel initiatingPartyOrganizationDataModel;

	private DataModel documentsModel;

	private Logger LOG = Logger.getLogger(CaseDetailsPage.class);

	private String caseCaption;

	private List<Documents> documentList;

	private String jurisdiction;
	
	/**
	 * Constructor
	 *
	 */
	public CaseDetailsPage() {
		this.loadData();
	}

	/**
	 * This method loads the data for a particular case record from the database 
	 *
	 */
	private void loadData() {

		Map sessionMap = this.getFacesContext().getExternalContext()
				.getSessionMap();
		String courtUuid = (String) sessionMap.get("courtUuid");
		
		try {
			this.setJurisdiction(LocalCaseInformation.getJurisdiction(courtUuid));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		String caseUuid = (String) sessionMap.get("caseUuid");
		CaseRecord c = (CaseRecord) this.getModelFacade().findCaseRecordById(
				caseUuid, courtUuid);
				
		// b7006e6c-695c-11dd-945f-00301b45ff56
		Hibernate.initialize(c.getPersonParticipants());
		Hibernate.initialize(c.getOrgParticipants());
		Hibernate.initialize(c.getDocuments());

		List<PersonParticipants> pParticipantsList = c.getPersonParticipants();
		List<OrgParticipants> oParticipantsList = c.getOrgParticipants();		

		List initiatingPartyOrganizationList = new ArrayList();

		// for initiating party person list
		List initiatingPartyPersonList = new ArrayList();

		// for defendant party person list
		List defendentPartyPersonList = new ArrayList();

		// for witness person list
		List witnessPersonList = new ArrayList();

		// for plantiff's Attorneys
		List plantiffsAttorneyList = new ArrayList();

		// for defendent's Attorneys
		List defendentsAttorneyList = new ArrayList();

		for (OrgParticipants o : oParticipantsList) {
			if (o.getRelationship().getCode() == 1)
				initiatingPartyOrganizationList.add(o);
		}

		for (PersonParticipants o : pParticipantsList) {
			if (o.getRelationship().getCode() == 1)
				initiatingPartyPersonList.add(o);
			else if (o.getRelationship().getCode() == 2)
				defendentPartyPersonList.add(o);
			else if (o.getRelationship().getCode() == 3)
				witnessPersonList.add(o);
			else if (o.getRelationship().getCode() == 4 && !o.getPerson().getFirstName().equalsIgnoreCase("ff20da2c-8e5c-11dd-9b78-0016d3"))
				plantiffsAttorneyList.add(o);
			else if (o.getRelationship().getCode() == 5)
				defendentsAttorneyList.add(o);
			else if (o.getRelationship().getCode() == 6) {
				Person filer = o.getPerson();
				this.setFilerName(filer.getFirstName() + " "
						+ filer.getMiddleName() + " " + filer.getLastName());
			}
		}

		initiatingPartyOrganizationDataModel = new ListDataModel();
		initiatingPartyOrganizationDataModel
				.setWrappedData(initiatingPartyOrganizationList);

		initiatingPartyPersonModel = new ListDataModel();
		initiatingPartyPersonModel.setWrappedData(initiatingPartyPersonList);

		defendentPartyPersonModel = new ListDataModel();
		defendentPartyPersonModel.setWrappedData(defendentPartyPersonList);

		witnessPersonModel = new ListDataModel();
		witnessPersonModel.setWrappedData(witnessPersonList);

		defendentsAttorneyModel = new ListDataModel();
		defendentsAttorneyModel.setWrappedData(defendentsAttorneyList);

		plantiffsAttorneyModel = new ListDataModel();
		plantiffsAttorneyModel.setWrappedData(plantiffsAttorneyList);
		
		
		List<Documents> pdfList = new ArrayList<Documents>();
		 
		for (Documents doc : c.getDocuments()){
			if (doc.getPhysicalType().equalsIgnoreCase("pdf"))
				pdfList.add(doc);				
		}
		this.setDocumentList(pdfList);	

		documentsModel = new ListDataModel();
		documentsModel.setWrappedData(this.getDocumentList());

		this.setCaseRecord(c);
		// set court date
		this.setCourtDate(this.getModelFacade().findCourtDate(
				this.getCaseRecord().getUuid()));
		// set case caption
		if (!initiatingPartyOrganizationList.isEmpty()) {
			String initiatingPartyOrgName = ((OrgParticipants) initiatingPartyOrganizationList
					.get(0)).getOrganizations().getName();
			if (!defendentPartyPersonList.isEmpty()) {
				Person defendent = ((PersonParticipants) defendentPartyPersonList
						.get(0)).getPerson();
				String defendentName = defendent.getFirstName() + " "
						+ defendent.getMiddleName() + " "
						+ defendent.getLastName();
				this.setCaseCaption(initiatingPartyOrgName + " vs "
						+ defendentName);
			}
		}

	}

	/**
	 * @return Returns the courtDate
	 */
	public Date getCourtDate() {
		return courtDate;
	}

	/**
	 * @param courtDate The courtDate to set
	 */
	public void setCourtDate(Date courtDate) {
		this.courtDate = courtDate;
	}

	/**
	 * @return Returns the proposedCourtDate
	 */
	public Date getProposedCourtDate() {
		return this.proposedCourtDate;
	}

	/**
	 * @param proposedCourtDate The proposedCourtDate to set
	 */
	public void setProposedCourtDate(Date proposedCourtDate) {
		this.proposedCourtDate = proposedCourtDate;
	}

	/**
	 * @return Returns the originalCourtDate
	 */
	public Date getOriginalCourtDate() {
		return this.originalCourtDate;
	}

	/**
	 * @param originalCourtDate The originalCourtDate to set
	 */
	public void setOriginalCourtDate(Date originalCourtDate) {
		this.originalCourtDate = originalCourtDate;
	}

	/**
	 * @param initiatingPartyOrganizationDataModel
	 *            The initiatingPartyOrganizationDataModel to set.
	 */
	public void setInitiatingPartyOrganizationDataModel(
			DataModel initiatingPartyOrganizationDataModel) {
		this.initiatingPartyOrganizationDataModel = initiatingPartyOrganizationDataModel;
	}

	/**
	 * @return Returns the caseRecord.
	 */
	public CaseRecord getCaseRecord() {
		return caseRecord;
	}

	/**
	 * @param caseRecord The caseRecord to set
	 */
	public void setCaseRecord(CaseRecord caseRecord) {
		this.caseRecord = caseRecord;
	}

	/**
	 * @return Returns the filerName
	 */
	public String getFilerName() {
		return filerName;
	}

	/**
	 * @param filerName The filerName to set
	 */
	public void setFilerName(String filerName) {
		this.filerName = filerName;
	}

	/**
	 * @return Returns the defendentPartyPersonModel
	 */
	public DataModel getDefendentPartyPersonModel() {
		return defendentPartyPersonModel;
	}

	/**
	 * @param defendentPartyPersonModel The defendentPartyPersonModel to set
	 */
	public void setDefendentPartyPersonModel(DataModel defendentPartyPersonModel) {
		this.defendentPartyPersonModel = defendentPartyPersonModel;
	}

	/**
	 * @return Returns the defendentsAttorneyModel
	 */
	public DataModel getDefendentsAttorneyModel() {
		return defendentsAttorneyModel;
	}

	/**
	 * @param defendentsAttorneyModel The defendentsAttorneyModel to set
	 */
	public void setDefendentsAttorneyModel(DataModel defendentsAttorneyModel) {
		this.defendentsAttorneyModel = defendentsAttorneyModel;
	}

	/**
	 * @return Returns the initiatingPartyPersonModel
	 */
	public DataModel getInitiatingPartyPersonModel() {
		return initiatingPartyPersonModel;
	}

	/**
	 * @param initiatingPartyPersonModel The initiatingPartyPersonModel to set
	 */
	public void setInitiatingPartyPersonModel(
			DataModel initiatingPartyPersonModel) {
		this.initiatingPartyPersonModel = initiatingPartyPersonModel;
	}

	/**
	 * @return Returns the initiatingPartyOrganizationDataModel
	 */
	public DataModel getInitiatingPartyOrganizationDataModel() {
		return initiatingPartyOrganizationDataModel;
	}

	/**
	 * @return Returns the witnessPersonModel
	 */
	public DataModel getWitnessPersonModel() {
		return witnessPersonModel;
	}

	/**
	 * @param witnessPersonModel The witnessPersonModel to set
	 */
	public void setWitnessPersonModel(DataModel witnessPersonModel) {
		this.witnessPersonModel = witnessPersonModel;
	}

	/**
	 * @return Returns the plantiffsAttorneyModel
	 */
	public DataModel getPlantiffsAttorneyModel() {
		return plantiffsAttorneyModel;
	}

	/**
	 * @param plantiffsAttorneyModel The plantiffsAttorney to set
	 */
	public void setPlantiffsAttorneyModel(DataModel plantiffsAttorneyModel) {
		this.plantiffsAttorneyModel = plantiffsAttorneyModel;
	}

	/**
	 * @return Returns the documentsModel
	 */
	public DataModel getDocumentsModel() {
		return documentsModel;
	}

	/**
	 * @param documentsModel The documentModel to set
	 */
	public void setDocumentsModel(DataModel documentsModel) {
		this.documentsModel = documentsModel;
	}

	/**
	 * @return Returns the caseCaption
	 */
	public String getCaseCaption() {
		return caseCaption;
	}

	/**
	 * @param caseCaption The caseCaption to set
	 */
	public void setCaseCaption(String caseCaption) {
		this.caseCaption = caseCaption;
	}

	/**
	 * @return Returns the documentList
	 */
	public List<Documents> getDocumentList() {
		return documentList;
	}

	/**
	 * @param documentList The documentList to set
	 */
	public void setDocumentList(List<Documents> documentList) {
		this.documentList = documentList;
	}

	/**
	 * @return the jurisdiction
	 */
	public String getJurisdiction() {
		return jurisdiction;
	}

	/**
	 * @param jurisdiction the jurisdiction to set
	 */
	public void setJurisdiction(String jurisdiction) {
		this.jurisdiction = jurisdiction;
	}

	/**
	 * This method gets called to view the PDF/XML File
	 * @return String
	 */
	public String viewFile() {
		Map requestMap = this.getFacesContext().getExternalContext()
				.getRequestParameterMap();
		FacesContext context = this.getFacesContext();
		HttpServletResponse resp = (HttpServletResponse) FacesContext
				.getCurrentInstance().getExternalContext().getResponse();
		String docTitle = (String) requestMap.get("title");

		byte[] docContent = null;
		for (Documents doc : this.getDocumentList()) {
			if (doc.getTitle().equalsIgnoreCase(docTitle)) {
				docContent = doc.getContent();
				break;
			}
		}
		try {
			this.streamReportToBrowser(resp, docTitle, docContent);
		} catch (IOException e) {
			LOG.error("Error in CaseDetailPage.viewFile() method: " + e);
			// throw e;
		}
		context.responseComplete();
		return "stay";
	}

	/**
	 * Helper method to view the PDF/XML file
	 * @param response
	 * @param fileName
	 * @param content
	 * @throws IOException
	 */
	private void streamReportToBrowser(HttpServletResponse response,
			String fileName, byte[] content) throws 
			IOException {

		response.setContentType("application/x-download");
	//	response.setContentType("application/pdf");

		response.setHeader("Content-Disposition", "attachment;filename= "
				+ fileName +".pdf");
		try {
			InputStream in = new ByteArrayInputStream(content);

			ServletOutputStream saos = response.getOutputStream();

			int inputdata;

			while ((inputdata = in.read()) > -1) {
				saos.write(inputdata);
			}
			saos.close();
			in.close();

		} catch (IOException ioEx) {
			LOG.error(ioEx);
			throw new IOException(ioEx.getMessage());
		}
	}

	/**
	 * This method navigates user to the Import Filing Page
	 * @return String
	 */
	public String gotoImportFiling() {
		return "gotoImportFiling";
	}

	/**
	 * This method navigates user to the Reject Filing Page
	 * @return String
	 */
	public String gotoRejectFiling() {
		return "gotoRejectFiling";
	}

	/**
	 * This method navigates user to the previous page
	 * @return String
	 */
	public String back() {
		Map sessionMap = this.getFacesContext().getExternalContext()
				.getSessionMap();
		String fromPage = (String) sessionMap.get("from");
		sessionMap.remove("from");
		sessionMap.remove("caseUuid");

		if (fromPage.equalsIgnoreCase("ChildEnforcementCaseTypePage")) {
			return "childEnforcement";
		} else if (fromPage.equalsIgnoreCase("ReceivedFilingPage")) {
			return "received";
		} else if (fromPage.equalsIgnoreCase("RejectedFilingPage")) {
			return "rejected";
		} else if (fromPage.equalsIgnoreCase("ImportedFilingPage")) {
			return "imported";
		} else if (fromPage.equalsIgnoreCase("DisposedFilingPage")) {
			return "disposed";
		} else if (fromPage.equalsIgnoreCase("TransmissionErrorFilingPage")) {
			return "transmissionError";
		} else if (fromPage.equalsIgnoreCase("ServedFilingPage")) {
			return "served";
		} else if (fromPage.equalsIgnoreCase("NonServedFilingPage")) {
			return "served";
		} else if (fromPage.equalsIgnoreCase("publicNewFilingPage")) {
			return "newFiling";
		} else if (fromPage.equalsIgnoreCase("AppellateCaseTypePage"))
			return "appellate";
		else if (fromPage.equalsIgnoreCase("CivilCaseTypePage"))
			return "civil";
		else if (fromPage.equalsIgnoreCase("childSupportTrashCanPage"))
			return "childSupportTrashCanPage";
		else if (fromPage.equalsIgnoreCase("MainPage"))
			return "gotoMainPage";	
		else if (fromPage.equalsIgnoreCase("searchPage")){
			sessionMap.put("from","MainPage");
			return "searchPage";
		}else
			return "";
	}
}